package com.wd.shared.io;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;

public class FileManager {

    private static Log log = LogFactory.getLog(FileManager.class);

    /**
     * Read a file based on the give path.
     * 
     * @param path
     * @return inputstream
     */
    public static InputStream readFile(String path) {
        File f = new File(path);
        if (!f.exists()) {
            return null;
        }
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(f);
        } catch (FileNotFoundException e) {
            log.error("FileNotFoundException : ", e);
        }
        return inputStream;
    }

    /**
     * Get buffered reader by given inputstream.
     * 
     * @param inputStream
     * @return bufferedReader
     */
    public static BufferedReader getBufferedReader(InputStream inputStream) {
        InputStreamReader reader = new InputStreamReader(inputStream);
        BufferedReader br = new BufferedReader(reader);
        return br;
    }

    public static byte[] readFileByte(String path) {
        File f = new File(path);
        if (!f.exists()) {
            return null;
        }
        
        int size = ((Long) f.length()).intValue();
        byte[] buf = new byte[size];
        FileInputStream inputStream = null;

        try {
            inputStream = new FileInputStream(f);
        } catch (FileNotFoundException e) {
            log.error("FileNotFoundException : ", e);
        }

        int offset = 0;
        int length = 0;
        try {
            while (size > 0) {
                length = inputStream.read(buf, offset, size);
                size -= length;
                offset += length;
            }
        } catch (IOException e) {
            log.error("IOException : ", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("", e);
                }
            }
        }
        return buf;
    }

    public static char[] readFileChar(String path, String charset) {
        File f = new File(path);
        if (!f.exists()) {
            return "".toCharArray();
        }
        int size = ((Long) f.length()).intValue();
        char[] buf = new char[size];
        FileInputStream inputStream = null;
        InputStreamReader reader = null;

        try {
            inputStream = new FileInputStream(f);
            reader = new InputStreamReader(inputStream, charset);
        } catch (FileNotFoundException e) {
            log.error("FileNotFoundException : ", e);
        } catch (UnsupportedEncodingException e) {
            log.error("", e);
        }

        int offset = 0;
        int length = 0;
        try {
            while (size > 0) {
                length = reader.read(buf, offset, size);
                size -= length;
                offset += length;

            }
        } catch (IOException e) {
            log.error("IOException : ", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error("", e);
                }
            }
        }

        return buf;
    }

    public static synchronized void writeFileBytes(String path, byte[] buf) {
        FileOutputStream output = null;
        File f = new File(path);
        File pF = f.getParentFile();
        if (!f.exists()) {
            if (pF != null && !pF.exists()) {
                pF.mkdirs();
            }
            try {
                f.createNewFile();
            } catch (IOException e) {
                log.error("", e);
            }
        }
        try {
            output = new FileOutputStream(f, false);
            output.write(buf);
        } catch (FileNotFoundException e) {
            log.error("FileNotFoundException : ", e);
        } catch (IOException e) {
            log.error("IOException : ", e);
        } finally {
            try {
                output.close();
            } catch (IOException e) {
                log.error("IOException : ", e);
            }
        }
    }

    public static synchronized void writeFileBytes(String path, byte[] buf,
            String charset) {
        FileOutputStream output = null;
        OutputStreamWriter writer = null;
        File f = new File(path);
        File pF = f.getParentFile();
        if (!f.exists()) {
            if (pF != null && !pF.exists()) {
                pF.mkdirs();
            }
            try {
                f.createNewFile();
            } catch (IOException e) {
                log.error(path, e);
                return;
            }
        }
        try {
            output = new FileOutputStream(f, false);
            writer = new OutputStreamWriter(output, charset);
            writer.write(new String(buf));
            writer.flush();
        } catch (FileNotFoundException e) {
            log.error("FileNotFoundException : ", e);
        } catch (IOException e) {
            log.error("IOException : ", e);
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
                if (output != null) {
                    output.close();
                }
            } catch (IOException e) {
                log.error("IOException : ", e);
            }
        }
    }

    /**
     * Get all children path list.
     * 
     * @param path
     * @return list path of children
     */
    public static String[] getFileChildrenList(String path) {
        File f = new File(path);
        String[] list = null;
        if (f.exists() && f.isDirectory()) {
            list = f.list();
        }
        return list;
    }

    private static void recursion(String path, List<String> tmpList) {
        File f = new File(path);
        if (f.exists() && f.isDirectory()) {
            File[] children = f.listFiles();
            for (File tmpf : children) {
                if (tmpf.isDirectory()) {
                    recursion(tmpf.getAbsolutePath(), tmpList);
                } else {
                    if (tmpList == null) {
                        break;
                    }
                    tmpList.add(tmpf.getAbsolutePath());
                }
            }
        }
    }

    public static String[] getFileChildrenListRecursion(String path) {
        String[] strs = null;
        if (!isFileExisted(path)) {
            return strs;
        }
        List<String> tmpList = new ArrayList<String>();
        recursion(path, tmpList);
        strs = tmpList.toArray(new String[tmpList.size()]);
        tmpList = null;
        return strs;
    }

    public static List<String> readLine(String path) {
        List<String> list = new ArrayList<String>();
        FileReader fr = null;
        BufferedReader br = null;
        String str = null;
        try {
            fr = new FileReader(path);
            br = new BufferedReader(fr);
            while ((str = br.readLine()) != null) {
                list.add(str.trim());
            }
        } catch (FileNotFoundException e) {
            log.error("FileNotFoundException : ", e);
        } catch (IOException ioe) {
            log.error("IOException : ", ioe);
        } finally {
            try {
                if (fr != null) {
                    fr.close();
                    br.close();
                }
            } catch (IOException e) {
                log.error("IOException : ", e);
            }
        }
        return list;
    }

    public static List<String> readGZLine(String path) {
        List<String> list = new ArrayList<String>();

        GZReader gzr = new GZReader(path);
        gzr.open();

        String line = "";
        while (line != null) {
            try {
                line = gzr.getNextLine();
            } catch (IOException e) {
                log.error("IOException : ", e);
            }
            if (line != null) {
                list.add(line);
            }
        }

        gzr.close();

        return list;
    }

    public static boolean removeFile(String path) {
        File f = new File(path);
        return f.delete();
    }

    public static boolean isFileExisted(String path) {
        File f = new File(path);
        if (f.exists()) {
            return true;
        }
        return false;
    }

    public static boolean isDirectory(String path) {
        File f = new File(path);
        return f.isDirectory();
    }

    public static void main(String args[]) {
        //        String path = "E:\\work\\project_J\\Test\\test\\0407_new.txt.gz";
        //        List<String> lines = FileManager.readGZLine(path);
        //        System.out.println("Total line : " + lines.size());
        //        for (String str : lines) {
        //            System.out.println(str);
        //        }
        PropertyConfigurator.configure("conf/log4j/log4j.properties");
                String path = "D:\\test\\tmp\\www.stc.org.cn\\stc_News_show.asp%3Fid%3D279_DCBB79A4806A066E8584A486EFCFABAD.htm";
//        String path = "D:\\test\\tmp\\www.stc.org.cn\\stc1.htm";
        String content = "中华人民共和国";
        writeFileBytes(path, content.getBytes(), "gb2312");
    }

}
